package net.sunbeta.testng;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

public class ClassScanner {

    /*    public void testInContainer() {
            TestNG tester = new TestNG();
            tester.setDefaultSuiteName("container-tests");
        }*/

    private File                rootDirectory;
    private FileFilter          filter;
    private ClassLoader         loader;

    private static final Logger LOG       = Logger.getLogger(ClassScanner.class);
    private static final String CLASS_EXT = ".class";

    public void setLoader(ClassLoader loader) {
        this.loader = loader;
    }

    public ClassScanner(File root) {
        this.rootDirectory = root;
    }

    public void setFilter(FileFilter filter) {
        this.filter = filter;
    }

    public Class[] getClasses() {
        List<Class> list = new ArrayList<Class>();
        loadClasses(list, rootDirectory);
        return list.toArray(new Class[list.size()]);
    }

    private void loadClasses(List<Class> list, File directory) {
        // superfluous check, but being explicit is a good thing
        // as we ensure we don't blow up if passed an invalid value
        if (directory == null || !directory.isDirectory())
            return;

        File[] files = directory.listFiles();
        for (File child : files) {
            // skip hidden files and dirs
            if (child.getName().charAt(0) == '.')
                continue;

            // we apply the filter manually because it's a very
            // common mistake for user-supplied filters to forget
            // about directories
            if (child.isDirectory()) {
                loadClasses(list, child);
            } else if (filter == null || filter.accept(child)) {
                int trim = rootDirectory.toString().length();
                String name = child.toString().substring(trim + 1);
                // get rid of the .class suffix
                name = name.substring(0, name.length() - CLASS_EXT.length());
                name = name.replace(File.separatorChar, '.');
                try {
                    Class clazz = (loader == null ? Class.forName(name) : loader.loadClass(name));
                    list.add(clazz);
                } catch (Exception e) {
                    LOG.warn("Error loading class " + name, e);
                }
            }
        }
    }
}
